package com.vichat.task;


import com.alibaba.dubbo.container.spring.SpringContainer;
import com.vichat.task.entity.CfgTask;
import com.vichat.task.entity.TaskLog;
import com.vichat.task.service.ITask;
import com.vichat.task.service.ITaskService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class TaskJob  implements Job
{
    private static transient Log log = LogFactory.getLog(TaskJob.class);
    private static final Map RUNNING_TASK = new ConcurrentHashMap();


    public void execute(JobExecutionContext context)
            throws JobExecutionException
    {
        ApplicationContext ctx = SpringContainer.getContext();
        ITaskService taskService = (ITaskService) ctx.getBean("taskService", ITaskService.class);
        CfgTask cfgTask = null;
        String taskResult = null;

        long taskId = 0L;
        try
        {
            JobDataMap data = context.getJobDetail().getJobDataMap();
            taskId = data.getLong("TASK_ID");

            cfgTask = taskService.getCfgTaskById(taskId);
        }
        catch (Throwable ex)
        {
            log.error("参数准备出现异常,任务ID:" + taskId + ",有可能的原因是,此任务已经加入调度,在执行的时候,此条任务数据已经被删除", ex);
            throw new JobExecutionException("参数准备出现异常,任务ID:" + taskId + ",有可能的原因是,此任务已经加入调度,在执行的时候,此条任务数据已经被删除", ex);
        }
        long taskLogId = 0L;
        try
        {
            taskLogId = insertStartTaskLog(cfgTask);

            ITask task = (ITask) ctx.getBean(cfgTask.getBusinessClass(), ITask.class);

            boolean isIgnore = false;
            try
            {
                if (taskId > 0L)
                {
                    if (RUNNING_TASK.containsKey(new Long(taskId)))
                    {
                        isIgnore = true;
                        throw new Exception("任务ID:" + taskId + ",检测到正在执行过程中,本次调度忽略");
                    }
                    RUNNING_TASK.put(new Long(taskId), new Long(taskId));
                }
                taskResult = task.doTask(cfgTask.getCfgTaskId());
            }
            finally
            {
                if ((taskId > 0L) && (!isIgnore)) {
                    RUNNING_TASK.remove(new Long(taskId));
                }
            }
            updateTaskLogSuccess(cfgTask, taskLogId, taskResult);
        }
        catch (Throwable ex)
        {
            log.error("执行任务出现异常", ex);

            updateTaskLogException(cfgTask, taskLogId, ex);
        }
    }

    protected long insertStartTaskLog(CfgTask cfgTask)
    {
        long rtn = 0L;
        try
        {
            ApplicationContext ctx = SpringContainer.getContext();
            ITaskService taskService = (ITaskService) ctx.getBean("taskService", ITaskService.class);
            TaskLog taskLog = new TaskLog();
            taskLog.setCfgTaskId(cfgTask.getCfgTaskId());
            taskLog.setStatus("C");
            rtn = taskService.insertTaskLog(taskLog);
        }
        catch (Throwable ex)
        {
            log.error("插入任务日志出现错误", ex);
        }
        return rtn;
    }

    protected void updateTaskLogSuccess(CfgTask cfgTask, long taskLogId, String taskResult)
    {
        try
        {
            ApplicationContext ctx = SpringContainer.getContext();
            ITaskService taskService = (ITaskService) ctx.getBean("taskService", ITaskService.class);
            taskService.updateTaskLog(taskLogId, "F", taskResult);
            if ((cfgTask.getTaskMethod().equals("I")) || (cfgTask.getTaskMethod().equals("F")))
            {
                cfgTask.setStatus("DONE");
                taskService.updateCfgTask(cfgTask);
            }

        }
        catch (Throwable ex2)
        {
            log.error("更新正常任务日志出现错误", ex2);
        }
    }

    protected void updateTaskLogException(CfgTask cfgTask, long taskLogId, Throwable ex)
    {
        String taskResult = ex.getMessage().length()> 1000 ? ex.getMessage().substring(0,950):ex.getMessage();
        try
        {
            ApplicationContext ctx = SpringContainer.getContext();
            ITaskService taskService = (ITaskService) ctx.getBean("taskService", ITaskService.class);
            taskService.updateTaskLog(taskLogId, "X", taskResult);
            if ((cfgTask.getTaskMethod().equals("I")) || (cfgTask.getTaskMethod().equals("F")))
            {
                cfgTask.setStatus("ERROR");
                taskService.updateCfgTask(cfgTask);
            }
         }
        catch (Throwable ex2)
        {
            log.error("更新异常任务日志出现错误", ex2);
        }
    }


}
